#include <magick/api.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "gmutils.h"
#include "utils.h"

int main1()
{
    Image *image1, *image2;
    ImageInfo *info1, *info2;
    int exit_status = 0;
    info1 = CloneImageInfo(0);
    info2 = CloneImageInfo(0);
    ExceptionInfo exception;
    register PixelPacket *q;
    uint8_t data[3][1500 * 1500];

    InitializeMagick(NULL);
    GetExceptionInfo(&exception);
    strcpy(info1->filename, "/home/xiefeihong/图片/1.png");
    strcpy(info2->filename, "/home/xiefeihong/图片/2.png");
    image1 = ReadImage(info1, &exception);
    image2 = ReadImage(info2, &exception);
    CompositeOperator compose = OverCompositeOp;
    CompositeImage(image1, compose, image2, 0, 0);
    strcpy(image1->filename, "/home/xiefeihong/图片/out.png");
    /*if(!WriteImage(info1, image1))
    {
        CatchException(&image1->exception);
        exit_status = 1;
        goto program_exit;
    }*/
    int i = 0;
    for (int x = 0; x < image1->rows; ++x)
    {
        for (int y = 0; y < image1->columns; ++y, i++)
        {
            q = GetImagePixels(image1, x, y, 1, 1);
            if (q == (PixelPacket *) NULL)
            {
                exit_status = 1;
                goto program_exit;
            }
            data[0][i] = (uint8_t) q->red;
            data[1][i] = (uint8_t) q->green;
            data[2][i] = (uint8_t) q->blue;
            printf("[x:%d, y:%d] : [r:%d, g:%d, b:%d]\n", x, y, data[0][i], data[1][i], data[2][i]);
        }
    }
    program_exit:
    if (image1 != NULL)
        DestroyImage(image1);
    if (image2 != NULL)
        DestroyImage(image2);
    if (info1 != NULL)
        DestroyImageInfo(info1);
    if (info2 != NULL)
        DestroyImageInfo(info2);
    DestroyMagick();
    return exit_status;
}

Image *image_compose(char *canvas_image_path, char *update_image_path) {
    Image *image1, *image2;
    ImageInfo *info1, *info2;
    info1 = CloneImageInfo(0);
    info2 = CloneImageInfo(0);
    ExceptionInfo exception;

    InitializeMagick(NULL);
    GetExceptionInfo(&exception);
    strcpy(info1->filename, canvas_image_path);
    strcpy(info2->filename, update_image_path);
    image1 = ReadImage(info1, &exception);
    image2 = ReadImage(info2, &exception);
    CompositeOperator compose = OverCompositeOp;
    CompositeImage(image1, compose, image2, 0, 0);
    if (image2 != NULL)
        DestroyImage(image2);
    if (info1 != NULL)
        DestroyImageInfo(info1);
    if (info2 != NULL)
        DestroyImageInfo(info2);
    return image1;
}

uint8_t **getrgb(Image *image)
{
    register PixelPacket *q;
    uint8_t **data;
    unsigned long rows, columns;
    rows = image->magick_rows;
    columns = image->magick_columns;
    unsigned long pixelNum = rows * columns * sizeof(uint8_t*);
    data = malloc(pixelNum * 3);
    int i = 0;
    data[0] = malloc(pixelNum);
    data[1] = malloc(pixelNum);
    data[2] = malloc(pixelNum);
    for (int y = 0; y < rows; y++)
    {
        for (int x = 0; x < columns; x++, i++)
        {
            q = GetImagePixels(image, x, y, 1, 1);
            data[0][i] = (uint8_t) q->red;
            data[1][i] = (uint8_t) q->green;
            data[2][i] = (uint8_t) q->blue;
//            printf("data[%d] : [x:%d, y:%d] : [r:%d, g:%d, b:%d]\n", i, x, y, data[0][i], data[1][i], data[2][i]);
        }
    }
    if (image != NULL)
        DestroyImage(image);
    DestroyMagick();
    return data;
}

uint8_t *getargbs(Image *image)
{
    register PixelPacket *q;
    unsigned long rows, columns;
    uint8_t *data;
    rows = image->magick_rows;
    columns = image->magick_columns;
    size_t data_size = rows * columns * sizeof(uint8_t*) * 4;
    data = malloc(data_size);
    int i = 0;
    for (int y = 0; y < rows; y++)
    {
        for (int x = 0; x < columns; x++)
        {
            uint8_t a;
            uint8_t r;
            uint8_t g;
            uint8_t b;
            q = GetImagePixels(image, x, y, 1, 1);
            a = (uint8_t) q->opacity;
            r = (uint8_t) q->red;
            g = (uint8_t) q->green;
            b = (uint8_t) q->blue;
            data[i] = a;
            i++;
            data[i] = r;
            i++;
            data[i] = g;
            i++;
            data[i] = b;
            i++;
//            printf("data[%d] : [x:%d, y:%d] : [r:%d, g:%d, b:%d]\n", i, x, y, data[0][i], data[1][i], data[2][i]);
        }
    }
    if (image != NULL)
        DestroyImage(image);
    DestroyMagick();
    return data;
}

uint8_t **getyuv(Image *image)
{
    register PixelPacket *q;
    uint8_t **data;
    unsigned long rows, columns;
    rows = image->magick_rows;
    columns = image->magick_columns;
    unsigned long pixelNum = rows * columns;
    data = malloc(sizeof(uint8_t*) * pixelNum);
    int i = 0;
    data[0] = malloc(pixelNum);
    data[1] = malloc(pixelNum);
    data[2] = malloc(pixelNum);
    uint8_t r, g, b, y2, cb, cr;
    for (int y = 0; y < rows; y++)
    {
        for (int x = 0; x < columns; x++, i++)
        {
            q = GetImagePixels(image, x, y, 1, 1);
            r = (uint8_t) q->red;
            g = (uint8_t) q->green;
            b = (uint8_t) q->blue;
            y2 = (FIX(0.29900) * r + FIX(0.58700) * g +
                       FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;
            cb = ((- FIX(0.16874) * r - FIX(0.33126) * g +
                        FIX(0.50000) * b + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
            cr = ((FIX(0.50000) * r - FIX(0.41869) * g -
                        FIX(0.08131) * b + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128;
            data[0][i] = y2;
            data[1][i] = cb;
            data[2][i] = cr;
//            printf("data[%d] : [x:%d, y:%d] : [r:%d, g:%d, b:%d]\n", i, x, y, r, g, b);
//            printf("data[%d] : [x:%d, y:%d] : [y:%d, cb:%d, cr:%d]\n", i, x, y, y2, cb, cr);
        }
    }
    if (image != NULL)
        DestroyImage(image);
    DestroyMagick();
    return data;
}

void getrgb2(Image *image)
{
    register PixelPacket *q;
    unsigned long rows, columns;
    uint8_t r, g, b;
    rows = image->magick_rows;
    columns = image->magick_columns;
    int i = 0;
    for (int y = 0; y < rows; y++)
    {
        for (int x = 0; x < columns; x++, i++)
        {
            q = GetImagePixels(image, x, y, 1, 1);
            r = (uint8_t) q->red;
            g = (uint8_t) q->green;
            b = (uint8_t) q->blue;
            put_pixel(x, y, r, g, b);
//            printf("data[%d] : [x:%d, y:%d] : [r:%d, g:%d, b:%d]\n", i, x, y, data[0][i], data[1][i], data[2][i]);
        }
    }
    if (image != NULL)
        DestroyImage(image);
    DestroyMagick();
}

Image *get_image(char *imagepath)
{
    Image *image;
    ImageInfo *info;
    info = CloneImageInfo(0);
    ExceptionInfo exception;

    InitializeMagick(NULL);
    GetExceptionInfo(&exception);
    strcpy(info->filename, imagepath);
    image = ReadImage(info, &exception);
    if (info != NULL)
        DestroyImageInfo(info);
    return image;
}